import java.util.ArrayList;
import java.util.Arrays;


/**
 * This class represents a sorting network
 * the network is represents as an array of int
 * each int is a code to an edge between two indexes of the input
 * 
 * 
 * @author Idan
 *
 */
public class SortingNetwork {

	public static NetworkEdge [] edgesCode ;
	
	
	/*
	 * statics init
	 * builds the codeing . each edge (1,2) (2,3) gets an int value
	 */
	
	static{
		ArrayList<NetworkEdge> array = new ArrayList<NetworkEdge>();
		for (int i = 1; i <= Constants.NETWORK_SIZE_INPUT; i++) {
			for (int j = i+1; j <= Constants.NETWORK_SIZE_INPUT; j++) {
				array.add(new NetworkEdge(i,j));
			}
		}
		
		edgesCode= new NetworkEdge[array.size()];
		int i=0;
		for (NetworkEdge networkEdge : array) {
			edgesCode[i]=networkEdge;
			i++;
		}
	}
	
	
	private ArrayList<Integer> network;
	/**
	 * creates an empty network
	 */
	public SortingNetwork() {

	}

	/**
	 * creates a sorting network
	 * 
	 * @param array
	 */
	public SortingNetwork(ArrayList<Integer> array) {
		this.network=array;
	}


	/**
	 * returns the array of int codes
	 * 
	 * @return
	 */
	public ArrayList<Integer> getNetwork() {
		return network;
	}


	/**
	 * saves a new int array
	 * 
	 * @param network
	 */
	public void setNetwork(ArrayList<Integer> network) {
		this.network = network;
	}
	
	@Override
	public String toString() {
	
		return network.toString();
	}
	
	
	/**
	 * This method performs the sorting network sort on the input.
	 * it performs the sort left to right 
	 * 
	 * @param input
	 * @return - an output done by the sorting network
	 */
	public int [] sortInput(int [] input){
		int [] out = Arrays.copyOf(input, input.length);

		for (Integer code: network) {
			NetworkEdge edge = SortingNetwork.edgesCode[code];
			if (out[edge.index1-1]>out[edge.index2-1]){
				int t=out[edge.index2-1];
				out[edge.index2-1]=out[edge.index1-1];
				out[edge.index1-1]=t;
			}
				
		}
		return out;
	}
	/**
	 * This method performs the sorting network sort on the input.
	 * it performs the sort right to left 
	 * 
	 * @param input
	 * @return - an output done by the sorting network
	 */
	public int [] sortInputRightToLeft(int [] input){
		int [] out = Arrays.copyOf(input, input.length);

		for (int i =network.size()-1; i >=0; --i) {
			NetworkEdge edge = SortingNetwork.edgesCode[network.get(i)];
			if (out[edge.index1-1]>out[edge.index2-1]){
				int t=out[edge.index2-1];
				out[edge.index2-1]=out[edge.index1-1];
				out[edge.index1-1]=t;
			}
		}
		
		return out;
	}
}
